home *** CD-ROM | disk | FTP | other *** search
- name execbeep
-
- dp equ dword ptr
- of equ offset
-
- code segment
- assume cs:code, ds:code
- org 2CH
- ENV_SEG dw ?
- org 80h
- TAIL_LENGTH db ?
- org 100h
-
- begin: jmp start
- prg_nam db 'EXECBEEP 3.0';
-
- beep proc ; beep the speaker
- push ax ; save
- push cx
- in al,97 ; get port values
- and al,0feh ; turn speaker on
- out 97,al
- mov cx,bx ; cycles to cx
- more_sound: push cx ; save cycles
- xor al,2 ; flip push/pull
- out 97,al
- mov cx,dx ; wait
- part1: loop part1
- xor al,2 ; flip push/pull
- out 97,al
- mov cx,dx ; wait
- part2: loop part2
- pop cx
- loop more_sound
- pop cx ; restore
- pop ax
- ret
- beep endp
-
- beep_low proc
- push bx
- push dx
- mov bx,50 ; number of cycles
- mov dx,100 ; half cycle time
- call beep
- pop dx
- pop bx
- ret
- beep_low endp
-
- beep_high proc
- push bx
- push dx
- mov bx,100 ; number of cycles
- mov dx,50 ; half cycle time
- call beep
- pop dx
- pop bx
- ret
- beep_high endp
-
- ; +++ EDR 2/27/88
-
- space db ' ',0 ; just a space
- cr_lf db 13,10,0 ; carriage return/line feed
-
- tty_str proc ; show string in ES:SI, max of CX chars
-
- jmp short load ; make sure string isn't null
-
- write: mov ah,0EH ; write TTY service (char in AL)
- int 10H ; kick BIOS
-
- inc si ; point to next char
- dec cx ; and decrement count
-
- load: mov al,es:[si] ; load char to show
- or al,al ; is it end of asciiz string?
- jz done ; yes
- cmp cx,0 ; did we reach max char count?
- jnz write ; no- write it
-
- done: ret
-
- tty_str endp
-
- show_cmd proc ; show the exec command line
-
- push ax ; save the world
- push cx
- push dx
- push si
- push di
- push es
- push bx
-
- mov ax,ds ; show command name from ds:dx
- mov es,ax
- mov si,dx
- mov cx,64
- call tty_str
- mov ax,cs ; followed by a space (just in case)
- mov es,ax
- mov si,offset space
- mov cx,64
- call tty_str
-
- pop bx ; get original es:bx back
- pop es
- push es
- push bx
-
- mov si,es:[bx+2] ; set es:si to command arguments
- mov ax,es:[bx+4]
- mov es,ax
-
- mov cl,es:[si] ; get char count in cx
- xor ch,ch
- inc si ; skip to actual command chars
- call tty_str ; and show 'em
-
- mov ax,cs ; skip up a line
- mov es,ax
- mov si,offset cr_lf
- mov cx,64
- call tty_str
-
- pop bx ; restore the world
- pop es
- pop di
- pop si
- pop dx
- pop cx
- pop ax
-
- ret ; back to caller
-
- show_cmd endp
-
- ; --- EDR
- old_dos_int label dword ; address
- old_int21 dw 2 dup(?) ; former int 21h address
-
- new_int21 proc far
- cmp ah,4bh ; EXEC function?
- je exec_beep ; yes, beep, then call EXEC
- cmp ah,4dh ; request to get return code?
- je retc_beep ; yes, beep then get return code
- jmp dp cs:old_int21 ; no, pass it on
-
- exec_beep: call beep_low ; beep before EXEC
- call show_cmd ; show the command (EDR)
- jmp dp cs:old_int21 ; go do EXEC
-
- retc_beep: call beep_high ; beep after EXEC
- jmp dp cs:old_int21 ; go get return code
- new_int21 endp
-
- END_OF_RES label word
-
- HELP1 DB 'Cannot Uninstall - Did not find copy in memory$'
- HELP2 DB 'Cannot Install - Found copy already in memory$'
- help3 db 'ExecBeep Uninstalled$'
- help10 db 'Cannot Uninstall - INT 21 in wrong segment$'
- help11 db 'Error - Dos Free Memory function failed$'
- help12 db 'Error - Restore of old INT 21 failed$'
- help20 db 'ExecBeep Installed$'
-
- alrdy_in_mem db 0
- other_seg dw 0
-
- start:
- assume cs:code, ds:code, es:code, ss:code
- ; Deallocate environment block
- push es
- mov es,env_seg ; get the segment from the PSP
- assume es:nothing
- mov ah,49h
- int 21h ; call DOS release memory function
- pop es
- assume es:code
- ; check for other copies of this program in memory
- find_copies:
- xor bx,bx
- mov word ptr [begin],bx
- mov ax,cs
- find_loop:
- inc bx ; check next segment
- mov es,bx ; use ES as segment pointer
- assume es:nothing
- cmp ax,bx ; have we found ourselves?
- je no_copies
- mov si,offset begin ; si is the offset pointer
- mov di,si ; look the same place in both segs
- mov cx,16 ; compare for 16 bytes
- cld ; increment pointers during compare
- repe cmpsb ; compabe bytes
- jne find_loop ; no match, keep looking
- inc alrdy_in_mem ; set already installed flag
- no_copies:
- mov other_seg,es ; save the segment for the copy
- ; that is already resident
- push cs
- pop es
- assume es:code
- mov di,offset tail_length ; use di to point to cmd line
- mov ax,1234h ; set ax to 1234h to indicate if
- ; a command was ever found
- find_command:
- inc di ;
- dec tail_length ;
- jl find_command_done ; are we at end of command line?
- cmp byte ptr [di],'u' ;
- je un_install
- cmp byte ptr [di],'U' ;
- je un_install
- jmp find_command ;
- un_install:
- cmp alrdy_in_mem,0 ; is there a resident copy?
- je disp_help1 ; No, so we cannot uninstall
- assume es:nothing
- mov ax,other_seg ; Make sure that ES points
- mov es,ax ; to the segment of the resident copy.
- call uninstall
- jc help_routine ; if CF set, error on uninstall
- mov dx,offset help3 ; "ExecBeep Uninstalled"
- jmp help_routine
-
- ;-----------------------------------------------------------------------------
- ;Print help lines.
- ;-----------------------------------------------------------------------------
- DISP_HELP1:
- MOV DX,OFFSET HELP1 ; Cannot Uninstall - not in memory
- HELP_ROUTINE:
- PUSH DX ;Save offset to message
- MOV AH,2 ;Output a carrage return
- MOV DL,10 ; to put a space between
- INT 21H ; the messages.
- POP DX ;Get back offset.
- MOV AH,9 ;DOS print string routine
- INT 21H
- mov ax,4c00h
- int 21h
-
- find_command_done:
- cmp alrdy_in_mem,0
- je carry_on
- mov dx,offset help2
- jmp help_routine
- carry_on:
- mov ax,3521h ; get int 21h
- int 21h
-
- mov old_int21,bx ; store offset
- mov old_int21+2,es ; store segment
- mov dx,of new_int21 ; ds:dx -> new int 21h
- mov ax,2521h
- int 21h
- mov dx,offset help20
- mov ah,9
- int 21h
- mov dx,of end_of_res ; discard excess
- add dx,0fh
- shr dx,1
- shr dx,1
- shr dx,1
- shr dx,1
- mov ax,3100h ; keep process
- int 21h
-
- ;-----------------------------------------------------------------------------
- ; UNINSTALL deallocates the memory block addressed by ES and restores the
- ; interrupt 21 vector displaced on installation.
- ; Exit: CF clear - program uninstalled
- ; CF set - can't uninstall
- ;-----------------------------------------------------------------------------
- UNINSTALL PROC NEAR
- ASSUME DS:CODE
- PUSH ES
- MOV AX,3521H ;Get int 21 vector
- INT 21H
- MOV AX,ES ;Compare vector segment with
- CMP AX,OTHER_SEG ; segment of installed code.
- JNE REMOVE_ERR1 ;If not the same, can't remove.
- ;-----------------------------------------------------------------------------
- ;Release the memory occupied by the program. ES already has proper segment.
- ;-----------------------------------------------------------------------------
- MOV AH,49H ;DOS free memory function
- INT 21H
- JC REMOVE_ERR2 ;If carry, error on removal
- ;-----------------------------------------------------------------------------
- ;Restore interrupt 21h vector.
- ;-----------------------------------------------------------------------------
- PUSH DS
- LDS DX,ES:[OLD_DOS_INT] ;Get old vector from installed
- MOV AX,2521H ; code.
- INT 21H ;Set int 21 to old vector.
- POP DS
- JC REMOVE_ERR3 ;If error, report and exit.
- ;-----------------------------------------------------------------------------
- ;Destroy the ASCII fingerprint that identifies the code and exit.
- ;-----------------------------------------------------------------------------
- NOT WORD PTR ES:[BEGIN]
- CLC ;Clear error flag
- REMOVE_EXIT:
- POP ES
- RET
- ;-----------------------------------------------------------------------------
- ;The program can't be uninstalled. Set CF and exit.
- ;-----------------------------------------------------------------------------
- REMOVE_ERR1:
- MOV DX,OFFSET HELP10 ;Point to error message.
- STC ;Set error flag
- JMP SHORT REMOVE_EXIT
- remove_err2:
- mov dx,offset help11
- stc
- jmp short remove_exit
- remove_err3:
- mov dx,offset help12
- stc
- jmp short remove_exit
- UNINSTALL ENDP
-
-
-
- code ends
- end begin
-